/*******************************************************************************
EntityManager.cpp

Notes:
*******************************************************************************/

#include "EntityManager.h"

// Initialize the instance to NULL
EntityManager* EntityManager::m_pInstance = NULL;

//	GetManager(void)
//		Returns the instance of the entity manager
EntityManager* EntityManager::GetManager(void)
{
	// If our instance isn't created yet...
	if(NULL == m_pInstance)
	{
		// ... create it
		m_pInstance = new EntityManager();
	}

	// Return the instance
	return m_pInstance;
} // GetManager(void)

//	~EntityManager(void)
//		Responsible for freeing memory
EntityManager::~EntityManager(void)
{
	// If necessary, delete and NULL the instance pointer
	if(NULL != m_pInstance)
	{
		delete m_pInstance;
		m_pInstance = NULL;
	} // if(NULL != m_pInstance)

	// Clean up our entities
	m_entityList.clear();
} // ~EntityManager(void)

//	CreateEntity(EntityResource& entityData)
//		Creates an entity
//			entityData - the information used to create an entity
EntityID EntityManager::CreateEntity(EntityResource& entityData)
{
	// If the entity resource type is the same as the paddle entity
	if(entityData.GetEntityType() == PaddleEntity::Type)
	{
		// Create a new paddle entity and controller
		PaddleEntity* pEntity = new PaddleEntity(entityData);

		PaddleController* pController = NULL;

		if(entityData.GetProperty("Control") == "player")
		{
			pController = new PaddleControllerPlayer();
		}
		else if(entityData.GetProperty("Control") == "cpu")
		{
			pController = new PaddleControllerCpu();
		}

		// Configure the controller
		pEntity->SetController(pController);
		ControllerManager::GetManager()->Add(pController);

		// Make sure we grab a unique ID
		EntityID entityID = 0;
		while(m_entityList.find(entityID) != m_entityList.end())
		{
			entityID++;
		} // while
		
		// Add the entity to our container
		m_entityList[entityID] = pEntity;

		// Return the entity ID
		return entityID;
	} // if
	// otherwise, if it is a Level entity
	else if(entityData.GetEntityType() == LevelEntity::Type)
	{
		// Create a new LevelEntity object
		LevelEntity* pEntity = new LevelEntity(entityData);

		// Find a unique ID
		EntityID entityID = 0;
		while(m_entityList.find(entityID) != m_entityList.end())
		{
			entityID++;
		} // while

		// Add the entity to the list
		m_entityList[entityID] = pEntity;

		// Return the ID
		return entityID;
	}
	// otherwise, if it is a Ball entity
	else if(entityData.GetEntityType() == BallEntity::Type)
	{
		// Create a new BallEntity object
		BallEntity* pEntity = new BallEntity(entityData);

		// Find a unique ID
		EntityID entityID = 0;
		while(m_entityList.find(entityID) != m_entityList.end())
		{
			entityID++;
		} // while

		// Add the entity to the list
		m_entityList[entityID] = pEntity;

		// Return the ID
		return entityID;
	}
	// otherwise...
	else
	{
		// -1 indicates an error creating the entity
		return -1;
	} // else
} // CreateEntity(EntityResource& entityData)


//	GetEntity(EntityID id)
//		Retrieves a pointer to the requested entity
//			id - The requested entity's ID
Entity* EntityManager::GetEntity(EntityID id)
{
	// If the id exists...
	if(m_entityList.find(id) != m_entityList.end())
	{
		// ... return the associated entity pointer
		return m_entityList[id];
	} // if
	else
	{
		// otherwise, return NULL to indicate an error
		return NULL;
	} // else
} // GetEntity

//	Update(float fElapsed)
//		Updates each of the entities
//			fElapsed - The time elapsed since the last update
void EntityManager::Update(float fElapsed)
{
	// Create an iterator to use to cycle through entities
	std::map<EntityID, Entity*>::iterator it;

	// Cycle through entities, updating each of them
	for(it = m_entityList.begin(); it != m_entityList.end(); it++)
	{
		Entity* pEntity = it->second;
		pEntity->Update(fElapsed);
	} // for
} // Update

//	EntityCount(void)
//		Returns the number of active entities
std::map<EntityID, Entity*>& EntityManager::GetEntityList(void)
{
	// Return the size of the entity list
	return m_entityList;
} // EntityCount